/********************************************************************
	filename: 	Trilinear.cpp
	created:	2010/04/22
	author:		Xiuwei Chen

	purpose:	Implement of trilinear coordinate

	All rights Reserved
*********************************************************************/


#include "Trilinear.h"
#include "GeoAlgorithm2D.h"

const Trilinear Trilinear::Zero = Trilinear(0, 0, 0);

/// <Summary>
/// default constructor
/// </Summary>
Trilinear::Trilinear()
	: u0(0), u1(0), u2(0)
{
}

/// <Summary>
/// copy constructor
/// </Summary>
Trilinear::Trilinear(const Trilinear& t)
	: u0(t.u0), u1(t.u1), u2(t.u2)
{
}

/// <Summary>
/// constructor
/// </Summary>
Trilinear::Trilinear(double _u0, double _u1, double _u2)
	: u0(_u0), u1(_u1), u2(_u2)
{
}

/// <Summary>
/// constructor
/// </Summary>
Trilinear::Trilinear(const Point2D &p, const Triangle2D &_triangle)
{
	SetValue(p, _triangle);
}

/// <Summary>
/// set value
/// </Summary>
void Trilinear::SetValue(double _u0, double _u1, double _u2)
{
	u0 = _u0;
	u1 = _u1;
	u2 = _u2;
}

/// <Summary>
/// set value
/// </Summary>
void Trilinear::SetValue(const Point2D &p, const Triangle2D &triangle)
{
	double area = triangle.AreaOriented();
	u0 = Triangle2D(p, triangle.p1, triangle.p2).AreaOriented() / (area * Distance(triangle.p1, triangle.p2));
	u1 = Triangle2D(p, triangle.p2, triangle.p0).AreaOriented() / (area * Distance(triangle.p2, triangle.p0));
	u2 = Triangle2D(p, triangle.p0, triangle.p1).AreaOriented() / (area * Distance(triangle.p0, triangle.p1));
}

/// <Summary>
/// overload operation: assignment
/// </Summary>
Trilinear & Trilinear::operator = (const Trilinear &t)
{
	u0 = t.u0;
	u1 = t.u1;
	u2 = t.u2;
	return *this;
}

/// <Summary>
/// overload operation: "=="
/// </Summary>
bool Trilinear::operator == (const Trilinear &t)
{
	return u0 == t.u0 && u1 == t.u1 && u2 == t.u2;
}

/// <Summary>
/// overload operation: "!="
/// </Summary>
bool Trilinear::operator != (const Trilinear &t)
{
	return u0 != t.u0 || u1 != t.u1 || u2 != t.u2;
}

/// <Summary>
/// Normalize
/// </Summary>
void Trilinear::Normalize()
{
	double sum = u0 + u1 + u2;
	if(sum != 0 && sum != 1)
	{
		u0 /= sum;
		u1 /= sum;
		u2 /= sum;
	}
}

/// <Summary>
/// sum of u0, u1, u2
/// </Summary>
double Trilinear::Sum()
{
	return u0 + u1 + u2;
}